const { connect } = require('./connectDatabase');

const mysqlHandleCurry = (fn) => {
  return (connection) => {
    return (sql, ...inParam) => {
      return fn(connection, sql, ...inParam);
    };
  };
};

const mysqlHandle = async (connection, sql, ...inParam) => {
  console.log('🚀 ~ mysqlHandle ~ inParam:', inParam);
  console.log('🚀 ~ mysqlHandle ~ sql:', sql);
  return new Promise((resolve, reject) => {
    connection.query(sql, inParam, (err, result) => {
      if (err) {
        console.error('执行预处理语句时出错:', err);
        reject(err);
      } else {
        resolve(result);
      }
    });
  });
};

const setResponse = (obj) => {
  const response = {
    code: obj.code,
    data: obj.data,
    total: obj.total,
    message: obj.message,
    success: obj.success || true,
  };

  if (obj.total === null || obj.total === undefined) {
    delete response.total;
  }
  return response;
};

const getSql = (fields = ['*'], paging, table) => {
  let sql = '';
  if (paging.page && paging.pageSize) {
    const page = paging?.page || 1;
    const pageSize = paging?.pageSize || 10;
    sql = `select ${fields.join(',')} from ${table} order by publish_date desc limit ${pageSize} offset ${(page - 1) * pageSize}`;
    console.log('🚀 ~ getSql ~ sql:', sql);
    return sql;
  } else {
    sql = `select ${fields.join(',')} from ${table}`;
    return sql;
  }
};
const postSql = (fields = [], table) => {
  let sql = '';
  let valueStr = '';
  fields.forEach((item, index) => {
    valueStr += index === fields.length - 1 ? '?' : '?, ';
  });
  sql = `insert into ${table} (${fields.join(',')}) values (${valueStr})`;
  console.log('🚀 ~ postSql ~ sql:', sql);
  return sql;
};

const updateSql = (fields = [], table) => {
  let sql = '';
  let fieldStr = '';
  fields.slice(0, fields.length - 1).forEach((item, index) => {
    fieldStr += index === fields.length - 2 ? `${item}=?` : `${item}=?,`;
  });
  sql = `update ${table} set ${fieldStr} where id=?`;
  console.log('🚀 ~ postSql ~ sql:', sql);
  return sql;
};

const deleteSql = (fields = [], table) => {
  let sql = '';
  sql = `delete from ${table} where ${fields[0]} in (?)`;
  console.log('🚀 ~ postSql ~ sql:', sql);
  return sql;
};

const getInterface = async (req, res) => {
  let connection;
  const { fields, table, query = {} } = req;
  console.log('🚀 ~ getInterface ~ query:', query);
  let _queryField = {};
  const keysToKeep = Object.keys(query).filter((key) => key !== 'page' && key !== 'pageSize');
  // 使用剩余的键来复制属性
  keysToKeep.forEach((key) => {
    _queryField[key] = query[key];
  });
  console.log('🚀 ~ keysToKeep.forEach ~ _queryField:', _queryField);
  const paging = {
    page: query?.page,
    pageSize: query?.pageSize,
  };
  try {
    connection = await connect();
    const excute = mysqlHandleCurry(mysqlHandle)(connection);
    let result = await excute(getSql(fields, paging, table));

    let total;
    if (paging.page && paging.pageSize) {
      total = await excute(`select count(*) as total from ${table}`);
    }
    Object.keys(_queryField).forEach((key) => {
      result = result.filter((item) => item[key] == query[key]);
    });

    const response = setResponse({
      code: 'SUCCESS',
      data: result,
      total: total?.[0]?.total,
      message: '',
      success: true,
    });

    if (!paging.page || !paging.pageSize) {
      delete response.total;
    }
    res.status(200).json(response);
  } catch (error) {
    const response = setResponse({
      code: 'FAILED',
      data: {},
      message: error,
      success: false,
    });
    res.status(500).json(response);
  } finally {
    if (connection) {
      connection.end();
    }
  }
};

const postInterface = async (req, res) => {
  let connection;
  try {
    const { fields, table } = req;
    const { url, title, publish_date } = req.body;
    connection = await connect();
    const excute = mysqlHandleCurry(mysqlHandle)(connection);
    const result = await excute(postSql(fields, table), url, title, publish_date);
    console.log('🚀 ~ postInterface ~ result:', result);
    if (!result.error) {
      const response = setResponse({
        code: 'SUCCESS',
        data: {},
        message: '',
        success: true,
      });
      res.status(200).json(response);
    } else {
      const response = setResponse({
        code: 'FAILED',
        data: {},
        message: result.error,
        success: false,
      });
      res.status(200).json(response);
    }
  } catch (error) {
    const response = setResponse({
      code: 'FAILED',
      data: {},
      message: error,
      success: false,
    });
    res.status(500).json(response);
  } finally {
    if (connection) {
      connection.end();
    }
  }
};

const putInterface = async (req, res) => {
  let connection;
  try {
    const { fields, table } = req;
    const { id, title, publish_date, url } = req.body;
    connection = await connect();
    const excute = mysqlHandleCurry(mysqlHandle)(connection);
    const result = await excute(updateSql(fields, table), url, title, publish_date, id);
    if (!result.error) {
      const response = setResponse({
        code: 'SUCCESS',
        data: {},
        message: '',
        success: true,
      });
      res.status(200).json(response);
    } else {
      const response = setResponse({
        code: 'FAILED',
        data: {},
        message: result.error,
        success: false,
      });
      res.status(200).json(response);
    }
  } catch (error) {
    console.log('🚀 ~ app.post ~ error:', error);
    const response = setResponse({
      code: 'FAILED',
      data: {},
      message: error,
      success: false,
    });
    res.status(500).json(response);
  } finally {
    if (connection) {
      connection.end();
    }
  }
};
const deleteInterface = async (req, res) => {
  let connection;
  try {
    const { fields, table } = req;
    connection = await connect();
    const excute = mysqlHandleCurry(mysqlHandle)(connection);
    await excute(deleteSql(fields, table), req.params.id);
    const response = setResponse({
      code: 'SUCCESS',
      data: {},
      message: '',
      success: true,
    });
    res.status(200).json(response);
  } catch (error) {
    const response = setResponse({
      code: 'FAILED',
      data: {},
      message: error,
      success: false,
    });
    res.status(500).json(response);
  } finally {
    if (connection) {
      connection.end();
    }
  }
};

module.exports = {
  getSql,
  postSql,
  updateSql,
  deleteSql,
  getInterface,
  postInterface,
  putInterface,
  deleteInterface,
  mysqlHandleCurry,
  mysqlHandle,
  setResponse,
};
